package com.kanas.webak.admin.domain;

import java.util.Date;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import javax.persistence.Table;
import javax.persistence.Transient;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

import com.kanas.app.web.security.PrincipalDetails;
import com.kanas.framework.support.AbstractModel;
import com.kanas.framework.util.StringUtils;
import com.kanas.webak.rbac.domain.AppRole;
import com.kanas.webak.rbac.domain.AppUserRole;

@Entity(name="KanasWebakUser")
@Table(name = "kanas_user")
@JsonIgnoreProperties({"password","userRoles","authorities"})
public class AppUser extends AbstractModel implements PrincipalDetails { 

	@Transient
	private static final long serialVersionUID = 1L;
	
	@Id
	@Column(name = "id", length = 32)
	private String id;
	@NotEmpty
	@Column(name = "username", length =100)
	private String username;
	@Column(name = "passwd", length = 128)
	private String password;
	@Column(name = "active_flag")
	private Boolean activeFlag  = true;
	@Column(name = "expired_flag")
	private Boolean expiredFlag = false;
	@Column(name = "locked_flag")
	private Boolean lockedFlag = false;
	@Column(name = "credentials_expired_flag")
	private Boolean credentialsExpiredFlag = false;
	@Column(name = "create_date")
	@Temporal(TemporalType.DATE)
	private Date createDate ;
	@Column(name = "last_login")
	@Temporal(TemporalType.DATE)
	private Date lastLogin;
	@Column(name = "last_change_pswd")
	@Temporal(TemporalType.DATE)
	private Date lastChangePassword;
	@Column(name = "login_failure_count")
	private Integer loginFailureCount;
	@Column(name = "login_ip")
	private String loginAddress;
	@Column(name = "display_name", length = 100)
	private String displayName;
	@Column(name = "default_portal", length = 100)
	private String defaultPortal;
	@Column(name = "user_portal", length = 100)
	private String userPortal;
	
	@OneToMany(mappedBy = "user", cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
	private Set<AppUserRole> userRoles;
	
	public AppUser() {
		this.id = StringUtils.generateUUID();
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	@Override
	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public Boolean getActiveFlag() {
		return activeFlag;
	}

	public void setActiveFlag(Boolean activeFlag) {
		this.activeFlag = activeFlag;
	}

	public Boolean getExpiredFlag() {
		return expiredFlag;
	}

	public void setExpiredFlag(Boolean expiredFlag) {
		this.expiredFlag = expiredFlag;
	}

	public Boolean getLockedFlag() {
		return lockedFlag;
	}

	public void setLockedFlag(Boolean lockedFlag) {
		this.lockedFlag = lockedFlag;
	}

	public Boolean getCredentialsExpiredFlag() {
		return credentialsExpiredFlag;
	}

	public void setCredentialsExpiredFlag(Boolean credentialsExpiredFlag) {
		this.credentialsExpiredFlag = credentialsExpiredFlag;
	}

	public Date getCreateDate() {
		return createDate;
	}

	public void setCreateDate(Date createDate) {
		this.createDate = createDate;
	}

	public Date getLastLogin() {
		return lastLogin;
	}

	public void setLastLogin(Date lastLogin) {
		this.lastLogin = lastLogin;
	}

	public Date getLastChangePassword() {
		return lastChangePassword;
	}

	public void setLastChangePassword(Date lastChangePassword) {
		this.lastChangePassword = lastChangePassword;
	}

	public Integer getLoginFailureCount() {
		return loginFailureCount;
	}

	public void setLoginFailureCount(Integer loginFailureCount) {
		this.loginFailureCount = loginFailureCount;
	}

	public String getLoginAddress() {
		return loginAddress;
	}

	public void setLoginAddress(String loginAddress) {
		this.loginAddress = loginAddress;
	}

	public String getDisplayName() {
		return displayName;
	}

	public void setDisplayName(String displayName) {
		this.displayName = displayName;
	}

	public String getDefaultPortal() {
		return defaultPortal;
	}

	public void setDefaultPortal(String defaultPortal) {
		this.defaultPortal = defaultPortal;
	}

	public String getUserPortal() {
		return userPortal;
	}

	public void setUserPortal(String userPortal) {
		this.userPortal = userPortal;
	}

	public Set<AppUserRole> getUserRoles() {
		if(userRoles == null) userRoles = new HashSet<AppUserRole>();
		return userRoles;
	}

	public void setUserRoles(Set<AppUserRole> roles) {
		this.userRoles = roles;
	}

	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {
		List<GrantedAuthority> ga=new ArrayList<GrantedAuthority>();
		for(AppUserRole r:this.getUserRoles()){
			ga.add(new SimpleGrantedAuthority(AppRole.ROLE_PREFIX+r.getRole().getId()));
		}
		return ga;
	}

	@Override
	public boolean isAccountNonExpired() {
		return this.expiredFlag==null?true:!this.expiredFlag;
	}

	@Override
	public boolean isAccountNonLocked() {
		return this.lockedFlag==null?true:!this.lockedFlag;
	}

	@Override
	public boolean isCredentialsNonExpired() {
		return this.credentialsExpiredFlag==null?true:!this.credentialsExpiredFlag;
	}

	@Override
	public boolean isEnabled() {
		return this.activeFlag==null?false:this.activeFlag;
	}

	@Override
	public String toIdString() {
		return id;
	}
	
	
}